package org.cupk2.main.cecurity.utils;

import org.cupk2.base.parameter.CupkParameterInter;
import org.cupk2.tools.caches.CupkCacheKeys;
import org.cupk2.tools.caches.CupkCaches;
import org.cupk2.tools.i18n.I18n;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * 安全登录相关
 */
@Component
public class CupkLoginSafeUtils {
    public static final String MATCHES_FALSEMSG = "验证码错误";
    @Autowired
    private CupkParameterInter cupkParameter;

    /**
     * 是否需要图形验证码（超过几次后）
     *
     * @param loginname
     * @return
     */
    public boolean isNeedImgCode(String loginname) {

        int imgcodeNum = cupkParameter.getIntParameter("cupk2.config.imgcode.limit");
        if (imgcodeNum == 0) {
            return true;
        }
        if (imgcodeNum == -1) {
            return false;
        }

        Integer loginErrorNum = CupkCaches.getInstance().getCacheData(loginname, CupkCacheKeys.LOGIN_ERROR_NUM);
        if (loginErrorNum == null) {
            loginErrorNum = 0;
        }
        if (loginErrorNum >= imgcodeNum) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 注册一个验证码
     *
     * @param loginname
     * @param imgCodeText
     */
    synchronized
    public void registImgCode(String loginname, String imgCodeText) {
        Set<String> codes = CupkCaches.getInstance().getCacheData(loginname, CupkCacheKeys.LOGIN_IMG_CODES);
        if (codes == null) {
            codes = new HashSet<>();
        }
        if (imgCodeText != null) {
            codes.add(imgCodeText.toUpperCase());
        }
        CupkCaches.getInstance().putCacheData(loginname, codes, CupkCacheKeys.LOGIN_IMG_CODES);
    }

    /**
     * 记录登录名和密码校验结果（为了出发验证码或锁定登录等行为）
     *
     * @param loginname
     * @param isSuccess 是否登录成功
     */
    synchronized
    public void registValidLoginResult(String loginname, boolean isSuccess) {
        if (!isSuccess) {

            Integer loginErrorNum = CupkCaches.getInstance().getCacheData(loginname, CupkCacheKeys.LOGIN_ERROR_NUM);
            if (loginErrorNum == null) {
                loginErrorNum = 1;
            } else {
                loginErrorNum++;
            }
            CupkCaches.getInstance().putCacheData(loginname, loginErrorNum, CupkCacheKeys.LOGIN_ERROR_NUM);
        } else {

            CupkCaches.getInstance().removeCacheData(loginname, CupkCacheKeys.LOGIN_IMG_CODES);
            CupkCaches.getInstance().putCacheData(loginname, 0, CupkCacheKeys.LOGIN_ERROR_NUM);
        }
    }

    /**
     * 校验用户录入的验证码和系统验证码是否匹配（一般在登录时使用）
     *
     * @param loginname
     * @param imgcode
     * @return
     */
    synchronized
    public boolean validImgCode(String loginname, String imgcode) {
        {//校验是否被锁定账户

            int lockNum = cupkParameter.getIntParameter("cupk2.config.login.lock");

            Integer loginErrorNum = CupkCaches.getInstance().getCacheData(loginname, CupkCacheKeys.LOGIN_ERROR_NUM);
            if (loginErrorNum == null) {
                loginErrorNum = 0;
            }
            if (loginErrorNum > lockNum) {
                throw new RuntimeException(I18n.msg("该账户被锁定，请10分钟后尝试"));
            }
        }
        {//处理验证码
            if (!isNeedImgCode(loginname)) {

                return true;
            }
            Set<String> codes = CupkCaches.getInstance().getCacheData(loginname, CupkCacheKeys.LOGIN_IMG_CODES);
            if (codes == null) {
                return false;
            }
            if (codes.contains(imgcode.toUpperCase())) {
                CupkCaches.getInstance().removeCacheData(loginname, CupkCacheKeys.LOGIN_IMG_CODES);
                return true;
            } else {
                return false;
            }
        }
    }
}
